<?php

require_once 'config/unitlist.php';
require_once 'config/magiclist.php';

class magic
{
    protected $turn;
    protected $category;
    protected $level;
    protected $name;
    protected $description;
    protected $flags;
    protected $value;
    protected $invocation_name;
    protected $log = array();

    public function __construct($turn, array $magic_definition)
    {
        $this->turn = $turn;
        $this->category = $magic_definition[0];
        $this->level = $magic_definition[1];
        $this->name = $magic_definition[2];
        $this->description = $magic_definition[3];
        $this->flags = $magic_definition[4];
        $this->value = $magic_definition[5];
        if (isset($magic_definition[6]))
            $this->invocation_name = $magic_definition[6];
    }

    public function has_flag($flag)
    {
        return in_array($flag, $this->flags);
    }

    protected function get_invocation_type()
    {
        if ($this->has_flag(_MAGIC_BONUS_ARCHERY_))
            return ARCHER;
        if ($this->has_flag(_MAGIC_BONUS_CAVALRY_))
            return CAVALRY;
        if ($this->has_flag(_MAGIC_BONUS_INFANTRY_))
            return INFANTRY;
        return NULL;
    }

    public function pop_log()
    {
        reset($this->log);
        $log = each($this->log);
        unset($this->log[$log['key']]);
        return $log['value'];
    }
    
    public function begin_hook($turn, army &$army, army &$opponent_army,
        hero &$hero, hero &$opponent_hero)
    {
        if ($turn != $this->turn)
        {
            return;
        }
        if ($this->has_flag(_MAGIC_TYPE_INVOCATION_))
        {
            return $this->invocation($army, $hero, $opponent_army);
        }
        if ($this->has_flag(_MAGIC_TYPE_LIFE_))
        {
            return $this->mod_life($army, $opponent_army, $hero);
        }
        if ($this->has_flag(_MAGIC_TYPE_ATTACK_) || $this->has_flag(_MAGIC_TYPE_DEFENSE_))
        {
            if ($this->has_flag(_MAGIC_TARGET_HERO_))
                ;
            return $this->mod_attr($army, $opponent_army, $hero, $opponent_hero);
        }
    }

    protected function mod_life(army &$army, army &$opponent_army, hero &$hero)
    {
        if ($this->has_flag(_MAGIC_ORIENTATION_BONUS_))
        {
            $target_army = $army;
            $mod = 1;
        }
        else if ($this->has_flag(_MAGIC_ORIENTATION_MALUS_))
        {
            $target_army = $opponent_army;
            $mod = -1;
        }
        else
        {
            throw new Exception('No magic orientation set');
        }
        $target_army->apply_magic($this->value * $hero->magic_level * $mod,
            ($this->has_flag(_MAGIC_VALUE_TYPE_RATIO_) ? _MAGIC_VALUE_TYPE_RATIO_ :
                ($this->has_flag(_MAGIC_VALUE_TYPE_EACH_) ? _MAGIC_VALUE_TYPE_EACH_ :
                    _MAGIC_VALUE_TYPE_FIXED_ )),
            $this->has_flag(_MAGIC_TARGET_ALL_));
    }

    protected function invocation(army &$army, hero &$hero, army &$opponent_army)
    {
        global $_UNIT_LIST;
        $type = $this->get_invocation_type();
        foreach ($_UNIT_LIST as $u)
        {
            if ($u[4] == $hero->race && $u[2] == $type)
            {
                if ($this->has_flag(_MAGIC_VALUE_TYPE_FIXED_))
                {
                    $max_power = $hero->magic_level * $this->value;
                }
                else if ($this->has_flag(_MAGIC_VALUE_TYPE_RATIO_))
                {
                    $max_power = $hero->magic_level * ($this->value / 100) * $opponent_army->get_power();
                }
                else
                    throw new Exception('No magic value type set !');
                $quantity = floor($max_power / $u[1]);
                $army->add_invocation(new unit($u[1], $u[2], $u[3], $quantity, $u[0] . ' (invocation)'), TRUE);
                return ;
            }
        }
    }
}
?>
